﻿using System.Runtime.Serialization;
using System.Windows.Media;
using System.Windows.Media.Imaging;

using Game.Common;
using Game.Common.Resources;
using Game.Common.Visitor;
using Game.ResourceLocator;
using Game.Terrain;
using Game.Types;

namespace Game.Objects
{
    [DataContract(Namespace="game")]
    public class Vehicle : ContainerBase, IVisitorElement
    {
        [DataMember(Name = "VehicleType")]
        public readonly VehicleType _VehicleType;
        
        [DataMember(Name="Owner")]
        public string _OwnerUrl;
        
        GameResources _Tank;
        GameMovement _Movement;
        Weapon _Weapon;
        GamePlayer _Owner;
        int _Experience;
        int _Armor;
        int _TargetingAccuracy;
        
        internal Vehicle()
        {
        }
        
        [OnDeserialized]
        public void OnDeserialized2(StreamingContext c)
        {
            if (_OwnerUrl != null)
            {
                object obj = GameResourceLocator.Get(_OwnerUrl);
                var t = obj as GamePlayer;
                if (t != null)
                {
                    _Owner = t;
                }
            }
            _Tank = new GameResources(_VehicleType.Tank);
            _Movement = _VehicleType.Movement.Copy(GameResources);
            _Weapon = new Weapon(_VehicleType.WeaponType);
            _Armor = (_VehicleType.Armor > 1) ? _VehicleType.Armor : 1;
            _TargetingAccuracy = 0;
            _Movement.Reset();
            _Movement.Changed += (source, args) => FireChanged();
            Extensions = _VehicleType.RuntimeExtensionFactories.GetExtensionCollection(this);
        }
        
        public Vehicle(VehicleType vehicleType)
            : base(vehicleType)
        {
            _VehicleType = vehicleType;
            _Tank = new GameResources(_VehicleType.Tank);
            _Movement = _VehicleType.Movement.Copy(_Tank);
            _Weapon = new Weapon(vehicleType.WeaponType);
            _Armor = (vehicleType.Armor > 1) ? vehicleType.Armor : 1;
            _TargetingAccuracy = 0;
            _Movement.Reset();
            _Owner = HumanPlayer.Player;
            _OwnerUrl = _Owner.Url;
            _Movement.Changed += (source, args) => FireChanged();
        }
        
        public VehicleType VehicleType
        {
            get { return _VehicleType; }
        }
        
        public ImageSource InfoImage
        {
            get { return _VehicleType.InfoImage; }
        }
        
        public ImageSource InfoImageSmall
        {
            get { return _VehicleType.InfoImageSmall; }
        }
        
        public GameResources Tank
        {
            get { return _Tank; }
        }
        
        public override GameResources GameResources 
        {
            get { return _Tank; }
        }
        
        public override GameMovement Movement
        {
            get { return _Movement; }
        }
        
        public Weapon Weapon
        {
            get { return _Weapon; }
        }

        public int Armor
        {
            get { return _Armor; }
        }
        
        public int TargetingAccuracy
        {
            get { return _TargetingAccuracy; }
        }
        
        public override ReadOnlyTerrainAccess TerrainAccess 
        {
            get { return _VehicleType.TerrainAccess; }
        }

        public override ImageSource Picture 
        {
            get { return _VehicleType.Picture; }
        }
        
        public int Experience
        {
            get { return _Experience; }
            set { _Experience=value; FireChanged(); }
        }
        
        public override GamePlayer Owner
        {
            get { return _Owner; }
            set 
            { 
                _Owner = value; 
                _OwnerUrl = _Owner.Url;
                DoPlayerChanged(); 
            }
        }
      
        public void Accept(IVisitor visitor)
        {
            visitor.Visit(this);
        }

        public override string ToString()
        {
            string s = "{" + VehicleType.Name + ":";
            if (Owner != null)
            {
                s += Owner;
            }
            s += "}";
            return s;
        }

    }
}
